package com.jwsoft.manager.core.integration.impl;

import cn.hutool.core.convert.Convert;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.bifang.engine.assistant.core.annotation.ApiService;
import com.bifang.engine.assistant.core.annotation.OpApi;
import com.bifang.engine.assistant.core.annotation.SaveOplog;
import com.bifang.engine.assistant.core.enums.AuTypeEnum;
import com.bifang.engine.assistant.core.enums.AuthStatusEnum;
import com.bifang.engine.assistant.core.enums.BoolEnum;
import com.bifang.engine.assistant.core.enums.FuncTypeEnum;
import com.bifang.engine.assistant.core.exception.AppException;
import com.bifang.engine.assistant.core.utils.SessionUtil;
import com.bifang.engine.data.core.util.PagerUtil;
import com.bifang.module.base.common.vo.system.UserVO;
import com.bifang.module.base.core.helper.DictHelper;
import com.bifang.module.base.core.integration.DictIntegration;
import com.bifang.module.base.core.integration.OperationPeriodIntegration;
import com.bifang.module.system.core.dao.model.SysOrg;
import com.bifang.module.system.core.dao.model.SysUser;
import com.bifang.module.system.core.dao.service.SysOrgService;
import com.bifang.module.system.core.dao.service.SysUserService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.jwsoft.manager.common.vo.HouseholdConsistenct.HouseholdConsistenctQueryVO;
import com.jwsoft.manager.common.vo.HouseholdConsistenct.HouseholdConsistenctVO;
import com.jwsoft.manager.common.vo.eduHousehold.EduHouseholdVO;
import com.jwsoft.manager.core.dao.model.*;
import com.jwsoft.manager.core.dao.service.*;
import com.jwsoft.manager.core.integration.HouseholdConsistencyIntegration;
import com.jwsoft.manager.core.integration.addressParse.SmartParse;
import com.jwsoft.manager.core.integration.common.DygxIntegration;
import com.jwsoft.manager.core.util.EduHelper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 户籍信息表业务实现类
 *
 * @author wangtao
 * @since 2022-12-02
 */
@ApiService(funcCode = "eduHousehold", title = "户籍信息表")
public class HouseholdConsistenctIntegrationImpl implements HouseholdConsistencyIntegration {
    @Autowired
    private EduHelper eduHelper;

    @Autowired
    public EduHouseholdService eduHouseholdService;

    @Autowired
    public DygxIntegration dygxIntegration;

    @Resource
    public OperationPeriodIntegration operationPeriodIntegration;

    @Autowired
    public EduAddressService eduAddressService;
    @Autowired
    public DictHelper dictHelper;
    @Autowired
    public EduStudentEnrollPreService eduStudentEnrollPreService;
    @Autowired
    public SmartParse smartParse;
    @Autowired
    public EduHouseService eduHouseService;
    @Autowired
    public EduHouseDetailService eduHouseDetailService;
    @Autowired
    public SysUserService sysUserService;
    @Autowired
    public SysOrgService sysOrgService;
    @Autowired
    public DictIntegration dictIntegration;
    @Autowired
    private EduAddressSchoolService eduAddressSchoolService;


    @Override
    @OpApi(funcCode = "householdConsistency0001", title = "房户一致查询", funcType = FuncTypeEnum.query)
    public PageInfo<HouseholdConsistenctVO> householdConsistency(HouseholdConsistenctVO vo) {
        String orgId = SessionUtil.getSessionInfo().getOrgId();
        LambdaQueryWrapper<SysUser> wrapper = new QueryWrapper<SysUser>().lambda().select(SysUser::getUserId).eq(SysUser::getOrgId, orgId);
        List<SysUser> userList = sysUserService.list(wrapper);//查询该组织下的处理房户一致的用户
        List<String> list = userList.stream().map(user -> user.getUserId()).collect(Collectors.toList());
        QueryWrapper<EduStudentEnrollPre> preQueryWrapper = new QueryWrapper<>();
        preQueryWrapper.lambda().eq(EduStudentEnrollPre::getYear, vo.getYear());
        if (StringUtils.isNotBlank(vo.getAreaCode())) {
            preQueryWrapper.lambda().eq(EduStudentEnrollPre::getAreaCode, vo.getAreaCode());
        }
        if (StringUtils.isNotBlank(vo.getIdcard())) {
            preQueryWrapper.lambda().eq(EduStudentEnrollPre::getIdcard, vo.getIdcard());
        }
        if (StringUtils.isNotBlank(vo.getFullName())) {
            preQueryWrapper.lambda().eq(EduStudentEnrollPre::getFullName, vo.getFullName());
        }
        if (StringUtils.isBlank(vo.getIdcard())&&StringUtils.isBlank(vo.getFullName())){
            preQueryWrapper.lambda().in(EduStudentEnrollPre::getConsistentUserId, list);
        }
        List<EduStudentEnrollPre> preList = eduStudentEnrollPreService.list(preQueryWrapper);
        List<HouseholdConsistenctVO> enrollPres = Convert.toList(HouseholdConsistenctVO.class, preList);
        for (HouseholdConsistenctVO pre : enrollPres) {
            LambdaQueryWrapper<EduHousehold> queryWrapper = new QueryWrapper<EduHousehold>().lambda()
                    .select(EduHousehold::getHouseholdId, EduHousehold::getIdcard, EduHousehold::getFullName, EduHousehold::getAddress, EduHousehold::getAddressId)
                    .eq(EduHousehold::getIdcard, pre.getIdcard());
            EduHousehold household = eduHouseholdService.getOne(queryWrapper);
            if (household == null) {
                continue;
            }
            pre.setHouseholdId(household.getHouseholdId());
            pre.setHouseholdAddress(household.getAddress());
            if (pre.getConsistentFlag().equals(BoolEnum.TRUE.getType()) && StringUtils.isNotBlank(pre.getHouseId())) {
                LambdaQueryWrapper<EduHouse> houseLambdaQueryWrapper = new QueryWrapper<EduHouse>()
                        .lambda().select(EduHouse::getHouseId, EduHouse::getAddress, EduHouse::getRealProperty)
                        .eq(EduHouse::getHouseId, pre.getHouseId());
                EduHouse house = eduHouseService.getOne(houseLambdaQueryWrapper);
                pre.setHouseAddress(house.getAddress());
                pre.setHouseId(house.getHouseId());
                pre.setRealProperty(house.getRealProperty());
            }
            if (pre.getConsistentFlag().equals(BoolEnum.TRUE.getType()) && pre.getConsistentType().equals(AuthStatusEnum.NO.getType())) {
                UserVO userVO = sysUserService.getUserDetail(pre.getConsistentUserId());
                pre.setConsistentUserName(userVO.getFullName());
                SysOrg org = sysOrgService.getOne(new QueryWrapper<SysOrg>().lambda().select(SysOrg::getOrgName).eq(SysOrg::getOrgId, userVO.getOrgId()));
                pre.setConsistentOrgName(org.getOrgName());
            }

        }
        // 开启分页
        if (vo.getPageNum() == null || vo.getPageSize() == null) {
            //如果不传入分页参数，默认最大取1000条
            vo.setPageNum(1);
            vo.setPageSize(1000);
        }
        PageHelper.startPage(vo.getPageNum(), vo.getPageSize());
        if (CollectionUtils.isEmpty(enrollPres)) {
            // 判断是否为空，为空则返回空参数
            return PagerUtil.createEmptyPagerInfo(vo.getPageNum(), vo.getPageSize());
        }
        // 不为空则获取分页结果
        PageInfo<HouseholdConsistenctVO> pageInfo = new PageInfo<>(enrollPres);
        return PagerUtil.parsePagerVo(enrollPres, pageInfo);
    }

    @Override
    @OpApi(funcCode = "householdConsistency0002", title = "查询学生户籍与房产是否一致", funcType = FuncTypeEnum.query)
    public List<HouseholdConsistenctVO> queryHouse(HouseholdConsistenctVO vo) {
        LambdaQueryWrapper<EduStudentEnrollPre> queryWrapper = new QueryWrapper<EduStudentEnrollPre>().lambda()
                .eq(EduStudentEnrollPre::getStudentEnrollPreId, vo.getStudentEnrollPreId());
        EduStudentEnrollPre enrollPres = eduStudentEnrollPreService.getOne(queryWrapper);
        ArrayList<HouseholdConsistenctVO> list = new ArrayList<>();
        if (StringUtils.isNotBlank(vo.getHouseId())) {
            EduHouse eduHouses = eduHouseService.getOne(new QueryWrapper<EduHouse>().lambda().eq(EduHouse::getHouseId, vo.getHouseId()));
            HouseholdConsistenctVO consistenctVO = new HouseholdConsistenctVO();
            consistenctVO.setHouseId(eduHouses.getHouseId());
            consistenctVO.setHouseAddress(eduHouses.getAddress());
            consistenctVO.setRealProperty(eduHouses.getRealProperty());
            list.add(consistenctVO);
        } else {
            List<String> familyHouse = getFamilyHouse(enrollPres, vo);
            for (String data : familyHouse) {
                EduHouse eduHouses = eduHouseService.getOne(new QueryWrapper<EduHouse>().lambda().eq(EduHouse::getHouseId, data));
                HouseholdConsistenctVO consistenctVO = new HouseholdConsistenctVO();
                consistenctVO.setHouseId(eduHouses.getHouseId());
                consistenctVO.setHouseAddress(eduHouses.getAddress());
                list.add(consistenctVO);
            }
        }
        return list;
    }

    @Override
    @OpApi(funcCode = "householdConsistency0003", title = "人工更新预报名房产户籍是否一致信息", funcType = FuncTypeEnum.update)
    @SaveOplog(
            operationType = "householdConsistency0003",
            operationName = "人工修改预报名房产户籍是否一致信息",
            dataType = "studentEnrollPreId",
            auType = AuTypeEnum.OTHER)
    @Transactional
    public void update(HouseholdConsistenctVO vo) {
        boolean isFhyz=true;
        if (StringUtils.isNotBlank(vo.getConsistentFlag())){
            if (vo.getConsistentFlag().equals(BoolEnum.TRUE.getType())){
                //比对通过才校验是否为房户一致
                isFhyz = checkFhyz(vo);
            }
        }
        if (!isFhyz) {
            throw new AppException("该学生的房产地址匹配到的学区与户籍地址匹配到的学区不同");
        }
        if (StringUtils.isBlank(vo.getStudentEnrollPreId())) {//学校端新增时更新预采集表
            LambdaQueryWrapper<EduStudentEnrollPre> queryWrapper = new QueryWrapper<EduStudentEnrollPre>().lambda()
                    .select(EduStudentEnrollPre::getStudentEnrollPreId)
                    .eq(EduStudentEnrollPre::getFullName, vo.getFullName())
                    .eq(EduStudentEnrollPre::getIdcard, vo.getIdcard());
            EduStudentEnrollPre enrollPres = eduStudentEnrollPreService.getOne(queryWrapper);
            if (ObjectUtils.isEmpty(enrollPres)) {
                throw new AppException("未查询到预采集信息");
            }
            vo.setStudentEnrollPreId(enrollPres.getStudentEnrollPreId());
        }
        UpdateWrapper<EduStudentEnrollPre> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().eq(EduStudentEnrollPre::getStudentEnrollPreId, vo.getStudentEnrollPreId())
                .set(EduStudentEnrollPre::getConsistentType, AuthStatusEnum.NO.getType())//设置房户一致比对类型为人工比对
                .set(EduStudentEnrollPre::getConsistentFlag, vo.getConsistentFlag())
                .set(EduStudentEnrollPre::getBeforeFlag, BoolEnum.FALSE.getType())//将预采集数据重置为未同步
                .set(EduStudentEnrollPre::getBeforeRemark, "未生成")
                .set(EduStudentEnrollPre::getHouseId, vo.getHouseId())
                .set(EduStudentEnrollPre::getHouseholdId, vo.getHouseholdId())
                .set(EduStudentEnrollPre::getConsistentTime, new Date())
                .set(EduStudentEnrollPre::getConsistentRemarks, vo.getConsistentRemarks())
                .set(EduStudentEnrollPre::getAborigineFlag, vo.getAborigineFlag())
                .set(EduStudentEnrollPre::getServiceAreaFlag, vo.getServiceAreaFlag())
                .set(EduStudentEnrollPre::getConsistentUserId, SessionUtil.getSessionInfo().getUserId());
        eduStudentEnrollPreService.update(updateWrapper);
    }

    @Override
    public boolean checkFhyz(HouseholdConsistenctVO vo) {
        boolean isFhyz=true;
        //根据户籍ID查询学区信息
        LambdaQueryWrapper<EduHousehold> householdLambdaQueryWrapper = new QueryWrapper<EduHousehold>()
                .lambda().select(EduHousehold::getAddressId).eq(EduHousehold::getHouseholdId, vo.getHouseholdId());
        EduHousehold eduHousehold = eduHouseholdService.getOne(householdLambdaQueryWrapper);
        if (eduHousehold == null) {
            throw new AppException("未查询到户籍信息");
        }
        LambdaQueryWrapper<EduAddressSchool> eqHousehold = new QueryWrapper<EduAddressSchool>().lambda()
                .eq(EduAddressSchool::getAddressId, eduHousehold.getAddressId())
                .eq(EduAddressSchool::getSchoolCategory,vo.getSchoolCategory());
        List<EduAddressSchool> houseHoldSchoolList = eduAddressSchoolService.list(eqHousehold);
        //根据要关联的房产查询学区信息
        LambdaQueryWrapper<EduHouse> houseLambdaQueryWrapper = new QueryWrapper<EduHouse>()
                .lambda().select(EduHouse::getAddressId).eq(EduHouse::getHouseId, vo.getHouseId());
        EduHouse eduHouse = eduHouseService.getOne(houseLambdaQueryWrapper);
        if (eduHouse == null) {
            throw new AppException("未查询到房产信息");
        }
        LambdaQueryWrapper<EduAddressSchool> eqHouse = new QueryWrapper<EduAddressSchool>().lambda()
                .eq(EduAddressSchool::getAddressId, eduHouse.getAddressId())
                .eq(EduAddressSchool::getSchoolCategory,vo.getSchoolCategory());
        List<EduAddressSchool> houseSchoolList = eduAddressSchoolService.list(eqHouse);
        //如果房产匹配到的学区不在户籍匹配到的学区中时不能修改，
        for (EduAddressSchool houseHold : houseHoldSchoolList) {
            //如果是原住民，房产可以为空可以修改
            if (houseHold.getNativeFlag().equals(BoolEnum.TRUE.getType())) {
                break;
            }
            List<EduAddressSchool> collect = houseSchoolList.stream().filter(item -> item.getSchoolId().equals(houseHold.getSchoolId())).collect(Collectors.toList());
            if (collect.size()>0){
                isFhyz=true;
            }else {
                isFhyz=false;
            }
        }
        return  isFhyz;
    }

    @Override
    @OpApi(funcCode = "householdConsistency0004", title = "查询学生户籍", funcType = FuncTypeEnum.query)
    public HouseholdConsistenctQueryVO queryHousehold(HouseholdConsistenctQueryVO vo) {
        Integer year = eduHelper.thisYear();
        LambdaQueryWrapper<EduHousehold> queryWrapper = new QueryWrapper<EduHousehold>().lambda().eq(EduHousehold::getFullName, vo.getFullName())
                .eq(EduHousehold::getIdcard, vo.getIdcard())
                .eq(EduHousehold::getAuthStatus, AuthStatusEnum.YES.getType())
                .eq(EduHousehold::getStatus, BoolEnum.TRUE.getType())
                .eq(EduHousehold::getYear, year);
        List<EduHousehold> households = eduHouseholdService.list(queryWrapper);
        if (households.size() > 1) {
            throw new AppException("查询到多条数据，请联系管理员核验");
        }
        HouseholdConsistenctQueryVO result = new HouseholdConsistenctQueryVO();
        for (EduHousehold household : households) {
            result = Convert.convert(HouseholdConsistenctQueryVO.class, household);
            result.setHouseholdAddress(household.getAddress());
        }
        return result;
    }

    @Override
    @OpApi(funcCode = "householdConsistency0005", title = "房户一致管理查询(管理员）", funcType = FuncTypeEnum.query)
    public PageInfo<HouseholdConsistenctVO> householdConsistencyGly(HouseholdConsistenctVO vo) {
        Integer year = eduHelper.thisYear();
        QueryWrapper<EduStudentEnrollPre> preQueryWrapper = new QueryWrapper<>();
        preQueryWrapper.lambda().eq(EduStudentEnrollPre::getYear, vo.getYear());
        if (StringUtils.isNotBlank(vo.getAreaCode())) {
            preQueryWrapper.lambda().eq(EduStudentEnrollPre::getAreaCode, vo.getAreaCode());
        }
        if (vo.getYear() != null) {
            preQueryWrapper.lambda().eq(EduStudentEnrollPre::getYear, vo.getYear());
        }
        if (StringUtils.isNotBlank(vo.getIdcard())) {
            preQueryWrapper.lambda().eq(EduStudentEnrollPre::getYear, vo.getYear());
        }
        if (StringUtils.isNotBlank(vo.getConsistentFlag())) {
            preQueryWrapper.lambda().eq(EduStudentEnrollPre::getConsistentFlag, vo.getConsistentFlag());
        }
        if (StringUtils.isNotBlank(vo.getOrgId())) {
            preQueryWrapper.lambda().eq(EduStudentEnrollPre::getOrgId, vo.getOrgId());
        }
        preQueryWrapper.lambda().gt(EduStudentEnrollPre::getConsistentType, BoolEnum.FALSE.getType());
        List<EduStudentEnrollPre> preList = eduStudentEnrollPreService.list(preQueryWrapper);
        List<HouseholdConsistenctVO> enrollPres = Convert.toList(HouseholdConsistenctVO.class, preList);
        for (HouseholdConsistenctVO pre : enrollPres) {
            LambdaQueryWrapper<EduHousehold> queryWrapper = new QueryWrapper<EduHousehold>().lambda()
                    .select(EduHousehold::getHouseholdId, EduHousehold::getIdcard, EduHousehold::getFullName, EduHousehold::getAddress, EduHousehold::getAddressId)
                    .eq(EduHousehold::getIdcard, pre.getIdcard())
                    .eq(EduHousehold::getYear, year);
            EduHousehold household = eduHouseholdService.getOne(queryWrapper);
            if (household == null) {
                continue;
            }
            pre.setHouseholdId(household.getHouseholdId());
            pre.setHouseholdAddress(household.getAddress());
            if (pre.getConsistentFlag().equals(BoolEnum.TRUE.getType()) && StringUtils.isNotBlank(pre.getHouseId())) {
                LambdaQueryWrapper<EduHouse> houseLambdaQueryWrapper = new QueryWrapper<EduHouse>()
                        .lambda().select(EduHouse::getHouseId, EduHouse::getAddress, EduHouse::getRealProperty)
                        .eq(EduHouse::getHouseId, pre.getHouseId())
                        .eq(EduHouse::getYear, year);
                EduHouse house = eduHouseService.getOne(houseLambdaQueryWrapper);
                pre.setHouseAddress(house.getAddress());
                pre.setHouseId(house.getHouseId());
                pre.setRealProperty(house.getRealProperty());
            }
            if (pre.getConsistentFlag().equals(BoolEnum.TRUE.getType()) && pre.getConsistentType().equals(AuthStatusEnum.NO.getType())) {
                UserVO userVO = sysUserService.getUserDetail(pre.getConsistentUserId());
                pre.setConsistentUserName(userVO.getFullName());
                SysOrg org = sysOrgService.getOne(new QueryWrapper<SysOrg>().lambda().select(SysOrg::getOrgName).eq(SysOrg::getOrgId, userVO.getOrgId()));
                pre.setConsistentOrgName(org.getOrgName());
            }

        }
        // 开启分页
        if (vo.getPageNum() == null || vo.getPageSize() == null) {
            //如果不传入分页参数，默认最大取1000条
            vo.setPageNum(1);
            vo.setPageSize(1000);
        }
        PageHelper.startPage(vo.getPageNum(), vo.getPageSize());
        if (CollectionUtils.isEmpty(enrollPres)) {
            // 判断是否为空，为空则返回空参数
            return PagerUtil.createEmptyPagerInfo(vo.getPageNum(), vo.getPageSize());
        }
        // 不为空则获取分页结果
        PageInfo<HouseholdConsistenctVO> pageInfo = new PageInfo<>(enrollPres);
        return PagerUtil.parsePagerVo(enrollPres, pageInfo);
    }

    @Override
    @OpApi(funcCode = "householdConsistency0006", title = "房户一致管理查询(管理员）", funcType = FuncTypeEnum.query)
    public EduHouseholdVO getHousehold(EduHouseholdVO vo) {
        if (StringUtils.isBlank(vo.getYear())){
            vo.setYear(String.valueOf(eduHelper.thisYear()));
        }
        LambdaQueryWrapper<EduHousehold> queryWrapper = new QueryWrapper<EduHousehold>().lambda()
                .eq(EduHousehold::getIdcard, vo.getIdcard())
                .eq(EduHousehold::getFullName, vo.getFullName())
                .eq(EduHousehold::getYear, vo.getYear())
                .eq(EduHousehold::getAuthStatus, AuthStatusEnum.YES.getType())
                .eq(EduHousehold::getStatus, AuthStatusEnum.YES.getType());
        EduHousehold household = eduHouseholdService.getOne(queryWrapper);

        return Convert.convert(EduHouseholdVO.class, household);
    }

    private List<String> getFamilyHouse(EduStudentEnrollPre pre, HouseholdConsistenctVO vo) {
        String real = Convert.toDBC(vo.getRealProperty());
        vo.setRealProperty(real);
        List<String> idcardList = new ArrayList<>();
        Integer year = eduHelper.thisYear();
        if (StringUtils.isNotBlank(pre.getIdcard())) {
            idcardList.add(pre.getIdcard());
        }
        if (StringUtils.isNotBlank(pre.getFatherIdcard())) {
            idcardList.add(pre.getFatherIdcard());
        }
        if (StringUtils.isNotBlank(pre.getMotherIdcard())) {
            idcardList.add(pre.getMotherIdcard());
        }
        QueryWrapper<EduHouseDetail> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .lambda()
                .in(EduHouseDetail::getIdcard, idcardList)
                .eq(EduHouseDetail::getYear, year)
                .eq(EduHouseDetail::getRealProperty, vo.getRealProperty());
        List<EduHouseDetail> detailList = eduHouseDetailService.list(queryWrapper);
//        if(CollectionUtils.isEmpty(detailList)){
//            throw  new AppException("未找到名下房产信息或房产证号有误");
//        }
        List<String> houseIdList = detailList.stream().map(EduHouseDetail::getHouseId).distinct().collect(Collectors.toList());
        return houseIdList;
    }

}
